using System;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine;
using SCG.SolarVengeanceEngine.BrainInfo;

namespace SCG.SolarVengeance.Brains
{
    public class Defender : Brain
    {        
        //challenge
        public override ChallengeLevel Challenge
        {
            get
            {
                return ChallengeLevel.Easy;
            }
        }

        //main Brain logic
        public override void Execute()
        {
            //Determine how many StarSystems we own
            int systemsOwned = 0;
            foreach (StarSystemInfo sys in StarSystems)
                if (sys.OwnedByMe)
                    systemsOwned++;

            //Count WarShips, Drones built
            int warShips = 0;
            int drones = 0;
            double droneRatio = 0;
            foreach (StarShipInfo ship in MyStarShips)
            {
                if (ship.ShipType == StarShipType.WarShip)
                    warShips++;
                else if (ship.ShipType == StarShipType.Drone)
                    drones++;
            }
            if (systemsOwned > 0)
                droneRatio = drones / (double)systemsOwned;

            //Give StarSystems orders
            foreach(StarSystemInfo system in StarSystems)
                if (system.OwnedByMe)
                {
                    //capital processing
                    if (system.IsCapital && warShips > 0 && Random(2, 7) < systemsOwned && droneRatio < 2.5)
                    {
                        if (system.Shields < 10)
                            BuildShields(system, 10);
                        else if (system.Resources > 15)
                            BuildStarShip(system, StarShipType.EMine, 1, 0, false);
                        else
                            BuildStarShip(system, StarShipType.Drone, Random(2, 8), 0, false);
                    }
                    else
                    {
                        if (system.Shields < system.Value / 2)
                            BuildShields(system, Random(2, 6));
                        else if (warShips > 0 && Random(1, 10) < 3 && systemsOwned > 2 && droneRatio < 2)
                            BuildStarShip(system, StarShipType.Drone, Random(2, 8), 0, false);
                        else
                        {
                            StarSystemInfo target = ClosestStarSystem(system.X, system.Y, 30, FindSystemFlags.VisibleUnfriendly);
                            if (target != null)
                            {
                                int wpn = target.Shields + 1;
                                int nbr = 1;
                                while (wpn > 6)
                                {
                                    wpn /= 2;
                                    nbr++;
                                }
                                while (nbr > 0)
                                {
                                    BuildStarShip(system, StarShipType.WarShip, Random(7, 13), wpn, false);
                                    nbr--;
                                }
                            }
                            else
                                BuildStarShip(system, StarShipType.WarShip, Random(7, 14), Random(3, 10), false);
                        }
                    }
                }

            //Give StarShips orders
            foreach (StarShipInfo ship in MyStarShips)
            {
                //WarShips are sent to conquer StarSystems
                if (ship.ShipType == StarShipType.WarShip)
                {
                    StarSystemInfo target = ClosestStarSystem(ship.X, ship.Y, Int32.MaxValue, FindSystemFlags.Unfriendly);
                    if (target != null)
                    {
                        Target(ship, target);
                        AttackAdjacent(ship, false);
                    }                  
                }
                else
                {
                    //Other ships are sent to explore nearby area, or defend closest StarSystem                  
                    if (ship.Order == OrderType.None)
                    {
                        if (Random(1, 10) > 5)
                        {
                            //attack nearby enemies
                            StarShipInfo enemy = ClosestStarShip(ship.X, ship.Y, 200, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (enemy != null)
                                Target(ship, enemy);
                            else
                            {
                                StarSystemInfo targetSystem = ClosestStarSystem(ship.X, ship.Y, Int32.MaxValue, FindSystemFlags.Unfriendly);
                                if (targetSystem != null)
                                {
                                    int x = targetSystem.X + Random(-10, 10);
                                    int y = targetSystem.Y + Random(-10, 10);
                                    Move(ship, x, y);
                                }
                            }
                        }
                        else
                        {
                            //defend closest StarSystem
                            StarSystemInfo system = ClosestStarSystem(ship.X, ship.Y, Int32.MaxValue, FindSystemFlags.Owned);
                            if (system != null)
                                Defend(ship, system);
                        }
                    }
                }
            }
        }

        //description
        public override string Description
        {
            get
            {
                return "Defender (as its name implies) adopts a mainly defensive posture, guarding its StarSystems " +
                    "carefully while slowly expanding its Empire.";
            }
        }
    }
}
